package com.example.web.template;

import com.alibaba.fastjson.JSON;
import com.example.common.enums.GlobalExceptionEnum;
import com.example.common.exception.AuthException;
import com.example.common.exception.UniversalException;
import com.example.common.utils.result.BaseResponse;
import com.example.web.helper.CheckTaskHelper;
import com.example.web.helper.DemoHelper;
import com.example.web.helper.RequestDataHelper;
import com.example.web.model.request.BaseReq;
import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * <p>
 *
 * </p>
 *
 * @author 12071
 * @date 2022/8/15 14:11
 */
@Slf4j
public class ApiWebTemplate {

    private final RateLimiter rateLimiter= RateLimiter.create(60);
    private ApiWebTemplate() {}

    private static final ApiWebTemplate Instance = new ApiWebTemplate();

    public static ApiWebTemplate INSTANCE() {
        return Instance;
    }

    /**
     * @param callback
     * @param <Response>
     * @return
     */
    public <Response, Request extends BaseReq> BaseResponse<Response> execute(
            ApiWebCallback<Response> callback, Request request) {
        try {
            //单机每台整体限流60次每秒
            if (!rateLimiter.tryAcquire()) {
                return null;
            }
            if(callback.loginPass){
                CheckTaskHelper.INSTANCE().doCheck(null);
            }
            callback.check();
            DemoHelper.INSTANCE().help();
            return BaseResponse.ok(callback.callback());
        } catch (AuthException e) {
            log.error("输入参数-->{}", JSON.toJSONString(request));
            return BaseResponse.fail(e.getCode(), e.getMessage());
        } catch (UniversalException e) {
            log.error("输入参数-->{}", JSON.toJSONString(request));
            DemoHelper.INSTANCE().help();
            return BaseResponse.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error("e={}", getStackTraceInfo(e));
            return BaseResponse.fail(
                    GlobalExceptionEnum.SYSTEM_EXCEPTION.getCode(),
                    GlobalExceptionEnum.SYSTEM_EXCEPTION.getMessage());
        } finally {
            RequestDataHelper.clean();
        }
    }


    private static String getStackTraceInfo(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try {
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
            return sw.toString();
        } catch (Exception ex) {
            return "异常信息转换错误";
        } finally {
            try {
                pw.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            try {
                sw.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
